<?php
/* 
* @Title: 图像处理类，包括缩略图操作与水印两个方法
* @Author: ChenLei [chenleib5@126.com]
* @Date:   2014-02-20 08:57:10
* @Last Modified by:   Administrator
* @Last Modified time: 2014-03-06 17:07:23
* @Copyright: Hn7m.com
*/
/**
 * 用PHP图像处理的前提是,必须装了GD库;
 * 所以在做题前,应该先判断是否存在GD库,以及GD库的版本.习惯上先建一个检测GD库的方法;
 * GD库，是php处理图形的扩展库，GD库提供了一系列用来处理图片的API，使用GD库可以处理图片，或者生成图片。
 */
class Image{

	/**
	 * [_check_gd 检测GD库是否存在]
	 * @return [type] [description]
	 */
	private function _check_gd(){
		return extension_loaded('GD');
	}

	//缩略图属性    
	//imagecopyresized(dst_image, src_image, dst_x, dst_y, src_x, src_y, dst_w, dst_h, src_w, src_h)
	
	private $thumbW;   	//缩略图的宽
	private $thumbH;	//缩略图的高
	private $thumbPath;	//缩略图保存位置
	private $prefix;	//缩略图名字的前缀

	/**
	 * [thumb 缩略图处理]
	 * @param  [type] $img       [要处理的图片]
	 * @param  [type] $thumbPath [指定保存路径]
	 * @param  [type] $thumbW    [指定缩略图宽]
	 * @param  [type] $thumbH    [指定缩略图高]
	 * @param  [type] $prefix    [缩略图命名的前缀]
	 * @return [type]            [在指定的文件夹保存并重命名缩略图]
	 */
	public function thumb($img,$thumbPath = NULL,$thumbW = NULL,$thumbH = NULL,$prefix =  NULL){
		//判断GD库是否存在
		if(!$this->_check_gd()) return false;
		//初始化数据
		$this->thumbW = is_null($thumbW) ? C('THUMB_WIDTH') : $thumbW;
		$this->thumbH = is_null($thumbH) ? C('THUMB_HEIGHT') : $thumbH;
		$this->prefix = is_null($prefix) ? C('THUMB_PREFIX') : $prefix;

		//获得图像信息
		$imgInfo = getimagesize($img);

		//获得原图宽与高
		$srcW = $imgInfo[0];
		$srcH = $imgInfo[1];

		//获得源图类型
		$type = ltrim(strrchr($imgInfo['mime'], '/'), '/');

		//STEP ONE : 打开源图
		$fn = 'imagecreatefrom' . $type;
		$srcImg = $fn($img); 

		//计算最佳缩放比例		
		$ratioW = $this->thumbW / $srcW;
		$ratioH = $this->thumbH / $srcH;
		$ratio = max($ratioH,$ratioW);

		//STEP TWO : 算出目标图的宽高
		$this->thumbW = $srcW * $ratio;
		$this->thumbH = $srcH * $ratio;

		//STEP THREE : 创建目标图，也就缩略图画布，透明处理
		if($type == 'gif'){
			//不用真彩色创建
			$dstImg = imagecreate($this->thumbW, $this->thumbH);
			//随便分配一个颜色，最后要抽走
			$color = imagecolorallocate($dstImg, 255, 0, 0);
		}else{
			$dstImg = imagecreatetruecolor($this->thumbW, $this->thumbH);
			//关闭混色通道
			imagealphablending($dstImg, false);
			//开启透明通道
			imagesavealpha($dstImg, true);
		}

		//STEP FOUR : 进行缩放动作
		//如果是GD库2.0用imagecopyresampled,效果好
		if(function_exists('imagecopyresampled')){
			imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $this->thumbW, $this->thumbH, $srcW, $srcH);
		}else{
			//如果是GD库1.0只能用imagecopyresized
			imagecopyresized($dstImg, $srcImg, 0, 0, 0, 0, $this->thumbW, $this->thumbH, $srcW, $srcH);
		}

		if($type == 'gif'){
			//抽走动作，可以让gif图像透明
			imagecolortransparent($dstImg, $color);
		}

		//获得图片信息，路径与名称
		$imgInfo = pathinfo($img);
		$path = is_null($thumbPath) ?  rtrim($imgInfo['dirname'],'/') . '/' : $thumbPath;
		//创建目录
		is_dir($path) || mkdir($path, 0777, true);
		//加前缀
		$filename = $this->prefix . $imgInfo['basename'];

		//STEP FIVEA:保存缩略图,并重命名
		$fn = 'image' . $type;
		//$fn($dstImg, $path . $filename);
		//STEP FIVEB:输出缩略图不保存
		$fn($dstImg);

		//STEP SIX 关闭图像释放资源;
		imagedestroy($srcImg);
		imagedestroy($dstImg);
		
		return true;
	}

	//水印属性
	//水印位置
	private $position;
	//水印不透明度
	private $alpha;
	//水印资源
	private $water;
	//保存质量
	private $quality;

	//用9宫格的方式来确定水印的位置
	private function _get_postion($dstW, $dstH, $srcW, $srcH){
		$arr['x'] = 20;
		$arr['y'] = 20;

		switch ($this->position) {
			case 1:				
				break;
			case 2:
				$arr['x'] = ($dstW - $srcW) / 2;			
				break;
			case 3:
				$arr['x'] = $dstW - $srcW - 20;			
				break;
			case 4:
				$arr['y'] = ($dstH - $srcH) / 2;				
				break;
			case 5:
				$arr['x'] = ($dstW - $srcW) / 2;			
				$arr['y'] = ($dstH - $srcH) / 2;				
				break;
			case 6:
				$arr['x'] = $dstW - $srcW - 20;	
				$arr['y'] = ($dstH - $srcH) / 2;				
				break;
			case 7:
				$arr['y'] = $dstH - $srcH - 20;		
				break;
			case 8:
				$arr['x'] = ($dstW - $srcW) / 2;	
				$arr['y'] = $dstH - $srcH - 20;			
				break;
			case 9:
				$arr['x'] = $dstW - $srcW - 20;	
				$arr['y'] = $dstH - $srcH - 20;		
				break;
		}

		return $arr; 
	}

	public function water($dst, $src, $position = NULL, $path = NULL, $alpha = NULL, $quality = NULL){
		//如果不存在GD库直接返回false;
		if(!$this->_check_gd()) return false;
		//初始化配置
		$this->position = is_null($position) ? C('WATER_POSTION') : $position;
		$this->alpha = is_null($alpha) ? C('WATER_ALPHA') : $alpha;
		$this->quality = is_null($quality) ? C('WATER_QUALITY') : $quality;

		//准备工作开始:
		
		$destInfo = getimagesize($dst);//获得目标图信息,即大图
		$srcInfo = getimagesize($src);//获得源图信息,即水印图
		
		$dstW = $destInfo[0];//获得目标图宽与高
		$dstH = $destInfo[1];
		$dstType = ltrim(strrchr($destInfo['mime'], '/'), '/');//获得目标图类型
		$srcW = $srcInfo[0];//获得原图宽与高
		$srcH = $srcInfo[1];
		$srcType = ltrim(strrchr($srcInfo['mime'], '/'), '/');//获得源图类型

		//准备工作结束:
		
		//STEP ONE : 打开目标图:
		$dstFn = 'imagecreatefrom' . $dstType;
		$dstImg = $dstFn($dst);

		//STEP TWO : 打开源图
		$srcFn = 'imagecreatefrom' . $srcType;
		$srcImg = $srcFn($src);

		//STEP THREE : 画9宫格用于后面确定水印的位置
		$positionArr = $this->_get_postion($dstW, $dstH, $srcW, $srcH);
		$x = $positionArr['x'];
		$y = $positionArr['y'];

		//STEP FOUR : 加盖水印
		if($srcType == 'png'){
			imagecopy($dstImg, $srcImg, $x, $y, 0, 0, $srcW, $srcH);
		}else{
			imagecopymerge($dstImg, $srcImg, $x, $y, 0, 0, $srcW, $srcH, $this->alpha);
		}

		//STEP FIVE : 处理保存路径
		$imgInfo = pathinfo($dst);
		$path = is_null($path) ?  rtrim($imgInfo['dirname'],'/') . '/' : $path;
		//创建目录
		is_dir($path) || mkdir($path, 0777, true);

		//组合文件名
		$filename = time() . mt_rand(0,999) . '.' . $dstType;
		//组合带有路径以及文件名完整信息
		$fullPath = $path . $filename;

		$fn = 'image' . $dstType;
		//保存图片
		// if($dstType == 'jpeg'){
		// 	$fn($dstImg, $fullPath, $this->quality);
		// }else{
		// 	$fn($dstImg, $fullPath);
		// }
		//只输出图片,不保存
		$fn($dstImg);
		
		//STEP SIX 关闭图像释放资源;
		imagedestroy($srcImg);
		imagedestroy($dstImg);

		return true;

	}
	
}

?>
